/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved.
 */

import { Heap } from '../../../../common/util/heap.js';
import { Priority } from '../enum/priority.js';
import { Work } from '../model/work.js';

import { ReadyQueue } from './ready-queue.js';

/**
 * ReadyQueue的实现类
 *
 * @since 2022/8/12
 */
export class PriorityReadyQueue implements ReadyQueue {
  private heap: Heap<Work>;

  constructor() {
    this.heap = new Heap(function (a, b) {
      return a.getPriority() - b.getPriority();
    });
  }

  clear(): void {
    this.heap.clear();
  }

  pop(): Work | undefined {
    return this.heap.pop();
  }

  push(work: Work): void {
    if (work.getPriority() === Priority.FIRST && this.hasFirstWork()) {
      const peek: Work = this.heap.pop()!;
      this.heap.push(work);
      this.heap.push(peek);
    } else {
      this.heap.push(work);
    }
  }

  update(work: Work): void {
    this.heap.update(work);
  }

  empty(): boolean {
    return this.heap.empty();
  }

  /**
   * 判断队列中是否存在FIRST优先级别的工作单元
   *
   * @returns {boolean} 判断结果
   */
  private hasFirstWork(): boolean {
    return !this.heap.empty() && this.heap.peek()!.getPriority() === Priority.FIRST;
  }
}
